/*
 * Copyright (c) 2012 Universidad Antonio de Nebrija.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Apache License v2.0
 * which accompanies this distribution, and is available at
 * http://www.apache.org/licenses/LICENSE-2.0.html
 * 
 * Contributors:
 *    Universidad Antonio de Nebrija - initial API, implementation and documentation
 */
package com.nebrija.riif.model;

import java.util.HashMap;
import java.util.Set;

import com.nebrija.riif.model.functions.AggGTNFail;
import com.nebrija.riif.model.functions.AggSingleFailFunction;
import com.nebrija.riif.model.functions.EXPFunction;
import com.nebrija.riif.model.functions.EmptyParenthesisFunction;
import com.nebrija.riif.model.functions.ExpressTimeFunction;
import com.nebrija.riif.model.functions.PowFunction;
import com.nebrija.riif.model.functions.environment.GetValue;
import com.nebrija.riif.model.functions.timeline.GetTimeSince;
import com.nebrija.riif.model.functions.timeline.GetTimeSinceLastTransition;

/**
 * Class implementing a registry where all the needed functions used in value calculations are stored
 * @author asanchep
 *
 */
public class FunctionRegistry {

	/** function implementation indexed by name */
	private HashMap<String, FunctionInterface> registry = new HashMap<String, FunctionInterface> ();
	
	/**
	 * Creates the registry
	 */
	public FunctionRegistry(){
		// TODO: Move this to a properties file or use Spring to inject dependencies
		// Add the empty function (resolve parentheses) and the functions used in the examples
		addFunction(new EXPFunction());
		addFunction(new EmptyParenthesisFunction());
		addFunction(new AggSingleFailFunction());
		addFunction(new AggGTNFail());
		addFunction(new GetTimeSinceLastTransition());
		addFunction(new GetValue());
		addFunction(new ExpressTimeFunction());
		addFunction(new PowFunction());
		addFunction(new GetTimeSince());
	}
	
	/**
	 * Adds a function to the registry. If a function exists with the same name it is replaced by the new one
	 * @param function the implementation to be added
	 */
	public void addFunction(FunctionInterface function){
		registry.put(function.getName(), function);
	}
	
	/**
	 * Returns a function given its name
	 * @param name the name of the function to be retrieved
	 * @return the implementation of the function
	 */
	public FunctionInterface getFunction(String name){
		return registry.get(name);
	}
	
	/**
	 * Getter for the function names in the registry
	 * @return a set with the names of the available functions
	 */
	public Set<String> getFunctions(){
		return registry.keySet();
	}
}
